package cn.wolfcode.p2p.business.service.impl;

import cn.wolfcode.p2p.base.query.PaymentScheduleQueryObject;
import cn.wolfcode.p2p.business.domain.BidRequest;
import cn.wolfcode.p2p.business.domain.PaymentSchedule;
import cn.wolfcode.p2p.business.domain.PaymentScheduleDetail;
import cn.wolfcode.p2p.business.mapper.PaymentScheduleMapper;
import cn.wolfcode.p2p.business.service.IPaymentScheduleDetailService;
import cn.wolfcode.p2p.business.service.IPaymentScheduleService;
import cn.wolfcode.p2p.util.CalculatetUtil;
import cn.wolfcode.p2p.util.PageResult;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Service
public class PaymentScheduleServiceImpl implements IPaymentScheduleService {
    @Autowired
    private PaymentScheduleMapper paymentScheduleMapper;

    @Autowired
    private IPaymentScheduleDetailService paymentScheduleDetailService;

    @Override
    public List<PaymentSchedule> loanPlan(BidRequest bidRequest) {
        Integer monthes2Return = bidRequest.getMonthes2Return();
        BigDecimal totalInterestTemp  = new BigDecimal("0.000");
        BigDecimal totalPrincipalTemp  = new BigDecimal("0.000");
        List<PaymentSchedule> paymentSchedules = new ArrayList<>();
        for (int i = 0; i < monthes2Return; i++) {
            PaymentSchedule paymentSchedule = new PaymentSchedule();
            Integer monthIndex = i + 1;
            paymentSchedule.setMonthIndex(monthIndex);
            paymentSchedule.setBidRequestType(bidRequest.getBidRequestType());
            paymentSchedule.setReturnType(bidRequest.getReturnType());
            paymentSchedule.setBidRequestId(bidRequest.getId());
            paymentSchedule.setBorrowUser(bidRequest.getCreateUser());
            paymentSchedule.setBidRequestTitle(bidRequest.getTitle());
            paymentSchedule.setBidRequestType(bidRequest.getBidRequestType());
            paymentSchedule.setDeadline(DateUtils.addMonths(bidRequest.getPublishTime(),monthIndex));
            if(i == (monthes2Return-1)){
                paymentSchedule.setInterest(bidRequest.getTotalRewardAmount().subtract(totalInterestTemp));
                paymentSchedule.setPrincipal(bidRequest.getBidRequestAmount().subtract(totalPrincipalTemp));
                paymentSchedule.setTotalAmount(paymentSchedule.getPrincipal().add(paymentSchedule.getInterest()));
            }else {
                BigDecimal totalAmount  = CalculatetUtil
                        .calMonthToReturnMoney(bidRequest.getReturnType(),bidRequest.getBidRequestAmount(),
                                bidRequest.getCurrentRate(),monthIndex,monthes2Return);
                paymentSchedule.setTotalAmount(totalAmount);
                BigDecimal interest = CalculatetUtil.calMonthlyInterest(bidRequest.getReturnType(),bidRequest.getBidRequestAmount(),
                        bidRequest.getCurrentRate(),monthIndex,monthes2Return);
                totalInterestTemp =  totalInterestTemp.add(interest);
                paymentSchedule.setInterest(interest);
                BigDecimal principal = totalAmount.subtract(interest);
                totalPrincipalTemp = totalPrincipalTemp.add(principal);
                paymentSchedule.setPrincipal(principal);
            }
            paymentScheduleMapper.insert(paymentSchedule);
            List<PaymentScheduleDetail> paymentScheduleDetails = paymentScheduleDetailService.collectionPlan(paymentSchedule, bidRequest.getBids(), bidRequest);
            paymentSchedule.setPaymentScheduleDetailLists(paymentScheduleDetails);
            paymentSchedules.add(paymentSchedule);
        }
        return paymentSchedules;

    }

    @Override
    public PageResult queryForPage(PaymentScheduleQueryObject qo) {
        int count = paymentScheduleMapper.queryForCount(qo);
        if (count == 0) {
            return PageResult.empty(qo.getPageSize());
        }
        int totalPage = count % qo.getPageSize() == 0 ? count / qo.getPageSize() : count / qo.getPageSize() + 1;
        if(totalPage < qo.getCurrentPage()){
            qo.setCurrentPage(totalPage);
        }
        List<PaymentSchedule> listData = paymentScheduleMapper.queryForList(qo);
        return new PageResult(listData,count,qo.getCurrentPage(),qo.getPageSize());

    }

    @Override
    public PaymentSchedule getPaymentSchedule(Long id) {
        return paymentScheduleMapper.selectByPrimaryKey(id);
    }

    @Override
    public int listPaymentScheduleStatesByBidRequestId(Long bidRequestId, int paymentState) {
        return paymentScheduleMapper.listPaymentScheduleStatesByBidRequestId(bidRequestId,paymentState);
    }

    @Override
    public void update(PaymentSchedule paymentSchedule) {
        paymentScheduleMapper.updatePayDateAndState(paymentSchedule);
    }

    @Override
    public void updateLatePayment(PaymentSchedule paymentSchedule) {
        paymentScheduleMapper.updateLatePayment(paymentSchedule);
    }

    @Override
    public List<PaymentSchedule> listPaymentScheduleByState(int state) {
        return paymentScheduleMapper.listPaymentScheduleByState(state);
    }
}
